package com.bird.framework.domain;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 延时队列Task
 *
 * @author 625
 * @version 创建时间：2018年6月16日 下午3:34:43
 */
public class DelayedTask<T extends Runnable> implements Delayed {
	/**
	 * 任务唯一性标志KEY
	 */
	private final String lockKey;
	/**
	 * 到期时间
	 */
	private final long time;

	/**
	 * 问题对象
	 */
	private final T task;

	/**
	 * 任务数量计数器
	 */
	private static final AtomicLong atomic = new AtomicLong(0);

	private final long n;

	public DelayedTask(long timeout, T t, String lockKey) {
		this.time = System.nanoTime() + timeout;
		this.task = t;
		this.lockKey = lockKey;
		this.n = atomic.getAndIncrement();
	}

	/**
	 * 返回与此对象相关的剩余延迟时间，以给定的时间单位表示
	 */
	@Override
	public long getDelay(TimeUnit unit) {
		return unit.convert(this.time - System.nanoTime(), TimeUnit.NANOSECONDS);
	}

	@Override
	public int compareTo(Delayed other) {
		// TODO Auto-generated method stub
		if (other == this) // compare zero ONLY if same object
		{
			return 0;
		}
		if (other instanceof DelayedTask) {
			DelayedTask<Runnable> x = (DelayedTask) other;
			long diff = time - x.time;
			if (diff < 0) {
				return -1;
			} else if (diff > 0) {
				return 1;
			} else if (getN() < x.getN()) {
				return -1;
			} else {
				return 1;
			}
		}
		long d = (getDelay(TimeUnit.NANOSECONDS) - other.getDelay(TimeUnit.NANOSECONDS));
		return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
	}

	public T getTask() {
		return this.task;
	}

	@Override
	public int hashCode() {
		return task.hashCode();
	}

	@Override
	public boolean equals(Object object) {
		if (object instanceof DelayedTask) {
			return object.hashCode() == hashCode() ? true : false;
		}
		return false;
	}

	public String getLockKey() {
		return lockKey;
	}

	public long getN() {
		return n;
	}

}
